home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 4 / Example 4.2 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  7.4 KB  |  273 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 4.2: Heightmaps from Perlin Noise                //
  3. // Written by: C. Granberg, 2005                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include "debug.h"
  9. #include "heightMap.h"
  10.  
  11. #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
  12. #define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
  13.  
  14. class APPLICATION
  15. {
  16.     public:
  17.         APPLICATION();
  18.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  19.         HRESULT Update(float deltaTime);
  20.         HRESULT Render();
  21.         HRESULT Cleanup();
  22.         HRESULT Quit();
  23.  
  24.     private:
  25.         IDirect3DDevice9* m_pDevice; 
  26.         HEIGHTMAP *m_pHeightMap;
  27.  
  28.         float m_angle;
  29.         int m_size, m_amplitude;
  30.         HWND m_mainWindow;
  31.         ID3DXFont *m_pFont;
  32. };
  33.  
  34. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  35. {
  36.     APPLICATION app;
  37.  
  38.     if(FAILED(app.Init(hInstance, 800, 600, true)))
  39.         return 0;
  40.  
  41.     MSG msg;
  42.     memset(&msg, 0, sizeof(MSG));
  43.     int startTime = timeGetTime(); 
  44.  
  45.     while(msg.message != WM_QUIT)
  46.     {
  47.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  48.         {
  49.             ::TranslateMessage(&msg);
  50.             ::DispatchMessage(&msg);
  51.         }
  52.         else
  53.         {    
  54.             int t = timeGetTime();
  55.             float deltaTime = (t - startTime)*0.001f;
  56.  
  57.             app.Update(deltaTime);
  58.             app.Render();
  59.  
  60.             startTime = t;
  61.         }
  62.     }
  63.  
  64.     app.Cleanup();
  65.  
  66.     return msg.wParam;
  67. }
  68.  
  69. APPLICATION::APPLICATION()
  70. {
  71.     m_pDevice = NULL; 
  72.     m_pHeightMap = NULL;
  73.     m_mainWindow = 0;
  74.     m_angle = 0.0f;
  75.     m_pFont = NULL;
  76.     m_size = 10;
  77.     m_amplitude = 5;
  78. }
  79.  
  80. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  81. {
  82.     debug.Print("Application initiated");
  83.  
  84.     //Create Window Class
  85.     WNDCLASS wc;
  86.     memset(&wc, 0, sizeof(WNDCLASS));
  87.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  88.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  89.     wc.hInstance     = hInstance;
  90.     wc.lpszClassName = "D3DWND";
  91.  
  92.     //Register Class and Create new Window
  93.     RegisterClass(&wc);
  94.     m_mainWindow = CreateWindow("D3DWND", "Example 4.2: Heightmaps from Perlin Noise", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  95.     SetCursor(NULL);
  96.     ShowWindow(m_mainWindow, SW_SHOW);
  97.     UpdateWindow(m_mainWindow);
  98.  
  99.     //Create IDirect3D9 Interface
  100.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  101.  
  102.     if(d3d9 == NULL)
  103.     {
  104.         debug.Print("Direct3DCreate9() - FAILED");
  105.         return E_FAIL;
  106.     }
  107.  
  108.     //Check that the Device supports what we need from it
  109.     D3DCAPS9 caps;
  110.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  111.  
  112.     //Hardware Vertex Processing or not?
  113.     int vp = 0;
  114.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  115.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  116.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  117.  
  118.     //Check vertex & pixelshader versions
  119.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  120.     {
  121.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  122.     }
  123.  
  124.     //Set D3DPRESENT_PARAMETERS
  125.     D3DPRESENT_PARAMETERS d3dpp;
  126.     d3dpp.BackBufferWidth            = width;
  127.     d3dpp.BackBufferHeight           = height;
  128.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  129.     d3dpp.BackBufferCount            = 1;
  130.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  131.     d3dpp.MultiSampleQuality         = 0;
  132.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  133.     d3dpp.hDeviceWindow              = m_mainWindow;
  134.     d3dpp.Windowed                   = windowed;
  135.     d3dpp.EnableAutoDepthStencil     = true; 
  136.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  137.     d3dpp.Flags                      = 0;
  138.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  139.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  140.  
  141.     //Create the IDirect3DDevice9
  142.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  143.                                  vp, &d3dpp, &m_pDevice)))
  144.     {
  145.         debug.Print("Failed to create IDirect3DDevice9");
  146.         return E_FAIL;
  147.     }
  148.  
  149.     //Release IDirect3D9 interface
  150.     d3d9->Release();
  151.  
  152.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  153.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  154.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  155.  
  156.     return S_OK;
  157. }
  158.  
  159. HRESULT APPLICATION::Update(float deltaTime)
  160. {
  161.     //Create Heightmap
  162.     if(m_pHeightMap == NULL)
  163.     {
  164.         //Create random heightmap
  165.         m_pHeightMap = new HEIGHTMAP(m_pDevice, INTPOINT(100,100));
  166.         if(FAILED(m_pHeightMap->CreateRandomHeightMap(rand()%2000, m_size / 10.0f, m_amplitude / 10.0f, 9)))
  167.         {
  168.             debug.Print("Failed to Create Random HeightMap");
  169.             Quit();
  170.         }
  171.  
  172.         if(FAILED(m_pHeightMap->CreateParticles()))
  173.         {
  174.             debug.Print("Failed to create particles");
  175.             Quit();
  176.         }
  177.     }
  178.     else
  179.     {
  180.         //Control camera
  181.         m_angle += deltaTime * 0.5f;
  182.         D3DXMATRIX  matWorld, matView, matProj;        
  183.         D3DXVECTOR2 centre = m_pHeightMap->GetCentre();
  184.         D3DXVECTOR3 Eye    = D3DXVECTOR3(centre.x + cos(m_angle) * centre.x * 1.5f, m_pHeightMap->m_maxHeight * 2.0f, -centre.y + sin(m_angle) * centre.y * 1.5f);
  185.         D3DXVECTOR3 Lookat = D3DXVECTOR3(centre.x, 0.0f,  -centre.y);
  186.  
  187.         D3DXMatrixIdentity(&matWorld);
  188.         D3DXMatrixLookAtLH(&matView, &Eye, &Lookat, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
  189.         D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.3333f, 1.0f, 1000.0f );
  190.  
  191.         m_pDevice->SetTransform( D3DTS_WORLD,      &matWorld );
  192.         m_pDevice->SetTransform( D3DTS_VIEW,       &matView );
  193.         m_pDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  194.  
  195.         if(KEYDOWN(VK_SPACE))
  196.         {
  197.             m_pHeightMap->CreateRandomHeightMap(rand()%2000, m_size / 10.0f, m_amplitude / 10.0f, 9);
  198.             m_pHeightMap->CreateParticles();
  199.         }
  200.     }
  201.  
  202.     if(KEYDOWN(VK_ESCAPE))
  203.         Quit();
  204.  
  205.     if(KEYDOWN(VK_DOWN) && m_size > 1){m_size--; Sleep(100);}
  206.     if(KEYDOWN(VK_UP) && m_size < 20){m_size++; Sleep(100);}
  207.     if(KEYDOWN(VK_LEFT) && m_amplitude > 1){m_amplitude--; Sleep(100);}
  208.     if(KEYDOWN(VK_RIGHT) && m_amplitude < 15){m_amplitude++; Sleep(100);}
  209.  
  210.     return S_OK;
  211. }    
  212.  
  213. HRESULT APPLICATION::Render()
  214. {
  215.     // Clear the viewport
  216.     m_pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L );
  217.  
  218.     // Begin the scene 
  219.     if(SUCCEEDED(m_pDevice->BeginScene()))
  220.     {
  221.         if(m_pHeightMap != NULL)m_pHeightMap->Render();
  222.  
  223.         //Write HeightMap variables
  224.         char number[50];
  225.         std::string sizeText = "Size: ";
  226.         sizeText += _itoa(m_size, number, 10);
  227.         sizeText += "     (UP/DOWN Arrow)";
  228.         RECT r1 = {110, 10, 0, 0};
  229.         m_pFont->DrawText(NULL, sizeText.c_str(), -1, &r1, DT_LEFT | DT_TOP | DT_NOCLIP, 0xffffffff);
  230.  
  231.         sizeText = "Persistance: ";
  232.         sizeText += _itoa(m_amplitude, number, 10);
  233.         sizeText += "     (LEFT/RIGHT Arrow)";
  234.         RECT r2 = {110, 30, 0, 0};
  235.         m_pFont->DrawText(NULL, sizeText.c_str(), -1, &r2, DT_LEFT | DT_TOP | DT_NOCLIP, 0xffffffff);
  236.  
  237.         RECT r3 = {110, 50, 0, 0};
  238.         m_pFont->DrawText(NULL, "Redraw: SPACE", -1, &r3, DT_LEFT | DT_TOP | DT_NOCLIP, 0xffffffff);
  239.  
  240.         // End the scene.
  241.         m_pDevice->EndScene();
  242.         m_pDevice->Present(0, 0, 0, 0);
  243.     }
  244.  
  245.     return S_OK;
  246. }
  247.  
  248. HRESULT APPLICATION::Cleanup()
  249. {
  250.     try
  251.     {
  252.         if(m_pHeightMap != NULL)
  253.         {
  254.             delete m_pHeightMap;
  255.             m_pHeightMap = NULL;
  256.         }
  257.  
  258.         m_pFont->Release();
  259.         m_pDevice->Release();
  260.  
  261.         debug.Print("Application terminated");
  262.     }
  263.     catch(...){}
  264.  
  265.     return S_OK;
  266. }
  267.  
  268. HRESULT APPLICATION::Quit()
  269. {
  270.     ::DestroyWindow(m_mainWindow);
  271.     ::PostQuitMessage(0);
  272.     return S_OK;
  273. }